#include "carplayExt.h"
#include "AppleCarPlay_AppStub.h"
#include "CarPlayInterface.h"

static UserInterfaceDelegate	userDelegate;
static CarPlayAppStubDelegate	c2iDelegate;
static ICarplayCallbacks *      globalCallbacks = nullptr;

SdCarplay::SdCarplay(ICarplayCallbacks* pcbs)
{
    mCallbacks = pcbs;
    globalCallbacks = mCallbacks;
    mAirPlayModeState = nullptr;
    mCarplayState = CarplayStateInit;
    mType = CARPLAY;
}

SdCarplay::~SdCarplay()
{
	if(globalCallbacks != nullptr )
	{
		globalCallbacks = nullptr;
	}
}

void _OnAirPlaySessionStarted(ipod_t handle){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->carplaySessionStart();
	}
}
/**
 * CarPlay会话停止了
 *
 */
void _OnAirPlaySessionStoped(ipod_t handle){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->carplaySessionStop();
	}
}
void _OnAirPlayDeviceInformationUpdate(const char* name, int len){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->NotifyDeviceNameCB(name, len);
	}
}
void _OnAirPlayiAP2LinkStatus(int status){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->iap2LinkStatus(status);
	}
}
int _OnAirPlayiAP2WriteData(const char* buf, int len){
	if(globalCallbacks != nullptr )
	{
		char temp [ len ];
		memset(temp,0,len);
		memcpy(temp,buf,len);
		return globalCallbacks->iap2WriteData(temp, len);
	}
	return 0;
}
void _OnAirPlaySessionStarted(){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->carplaySessionStart();
	}
}
void _OnAirPlaySessionStoped(){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->carplaySessionStop();
	}
}
int _OnAirPlayUsbRoleSwitch(int mode){
	if(globalCallbacks != nullptr )
	{
		return globalCallbacks->switchUsbModeCB(UsbHost);
	}
	return 0;
}
void _OnAirPlayDeviceTimeUpdate(long long time){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->appleTimeUpdateCB(time);
	}
}
void _OnAirPlayDeviceLanguageUpdate(const char* lang){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->appleLanguageUpdateCB(lang);
	}
}
void _OnAirPlayCallStateUpdate(const char* remoteId,
        const char* displayName,
        int status,
        int direction,
        const char* uuid,
        const char* addrBookId,
        const char* label,
        int service){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->appleCallStateUpdateCB(remoteId, displayName, status, direction, uuid, addrBookId, label, service);
	}
}

void _OnAirPlaySessionEnded(){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->carplayExitCB();
	}
}
void _OnAirPlayReturnNativeUI(){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->returnNativeUICB();
	}
}
void _OnAirPlaySessionModesChanged(int arg_screen,
        int arg_permScreen,
        int arg_audio,
        int arg_permAudio,
        int arg_speechEntity,
        int arg_speechMode,
        int arg_phoneCall,
        int arg_turnByTurn){
	if(globalCallbacks != nullptr )
	{
		CarPlayModeState modeState;
		modeState.phoneCall = arg_phoneCall;
		modeState.screen = arg_permScreen;
		modeState.mainAudio = arg_audio;
		globalCallbacks->modesChangeCB(&modeState);
	}
}
void _OnAirPlaySessionDisableBluetooth(){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->disableBluetoothCB();
	}
}
void _OnAirPlaySessionDuckAudio(double inDurationSecs, double inVolume){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->caplayDuckAudioCB(inDurationSecs, inVolume);
	}
}
void _OnAirPlaySessionUnduckAudio(double inDurationSecs){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->caplayUnduckAudioCB(inDurationSecs);
	}
}
void _OnAirPlaySessionAudioStreamStart(int handle, int type, int rate, int bits, int channels,
        void*  inStream){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->carplayAudioStartCB(handle, AudioStreamMedia, rate, bits, channels);
	}
}
void _OnAirPlaySessionAudioStreamStop(int handle, int type){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->carplayAudioStopCB(handle, AudioStreamMedia);
	}
}
int _OnAirPlaySessionScreenStreamStart(){
	if(globalCallbacks != nullptr )
	{
		return globalCallbacks->carplayVideoStartCB();
	}
	return 0;
}
void _OnAirPlaySessionScreenStreamStop(){
	if(globalCallbacks != nullptr )
	{
		globalCallbacks->carplayVideoStopCB();
	}
}
int _OnAirPlaySessionScreenStreamData(const uint8_t* buf, int len){
	if(globalCallbacks != nullptr )
	{
		return globalCallbacks->carplayVideoDataProcCB((const char *)buf, len);
	}
	return 0;
}

int SdCarplay::init()
{
	UserInterfaceDelegateInit( &userDelegate );
	userDelegate.useriAP2LinkStatus_f = _OnAirPlayiAP2LinkStatus;
	userDelegate.useriAP2WriteData_f = _OnAirPlayiAP2WriteData;
	userDelegate.userCarPlaySessionStart_f = _OnAirPlaySessionStarted;
	userDelegate.userCarPlaySessionStop_f = _OnAirPlaySessionStoped;
	userDelegate.userSwitchUsbMode_f = _OnAirPlayUsbRoleSwitch;
	userDelegate.userDeviceTimeUpdate_f = _OnAirPlayDeviceTimeUpdate;
	userDelegate.userDeviceLanguageUpdate_f = _OnAirPlayDeviceLanguageUpdate;
	userDelegate.userCallStateUpdate_f = _OnAirPlayCallStateUpdate;
	userDelegate.userDeviceInformationUpdate_f = _OnAirPlayDeviceInformationUpdate;
	userDelegate.userAirPlaySessionEnd_f = _OnAirPlaySessionEnded;
	userDelegate.userRequestUI_f = _OnAirPlayReturnNativeUI;
	userDelegate.userModesChanged_f = _OnAirPlaySessionModesChanged;
	userDelegate.userDisableBluetooth_f = _OnAirPlaySessionDisableBluetooth;
	userDelegate.userAirPlayDuckAudio_f = _OnAirPlaySessionDuckAudio;
	userDelegate.userAirPlayUnduckAudio_f = _OnAirPlaySessionUnduckAudio;
	userDelegate.userAirPlayAudioStreamStart_f = _OnAirPlaySessionAudioStreamStart;
	userDelegate.userAirPlayAudioStreamStop_f = _OnAirPlaySessionAudioStreamStop;
	userDelegate.userAirPlayScreenStreamStart_f = _OnAirPlaySessionScreenStreamStart;
	userDelegate.userAirPlayScreenStreamStop_f = _OnAirPlaySessionScreenStreamStop;
	userDelegate.userAirPlayScreenStreamData_f = _OnAirPlaySessionScreenStreamData;
	UserInterfaceSetDelegate( &userDelegate );

	CarPlayAppStubDelegateInit( &c2iDelegate );
	c2iDelegate.airPlaySessionStarted_f = _OnAirPlaySessionStarted;
	c2iDelegate.airPlaySessionStoped_f = _OnAirPlaySessionStoped;
	CarPlayAppStubSetDelegate( &c2iDelegate );
	StartAppleCarPlay(0, NULL);
	return 1;
}

int SdCarplay::start(LinkType type, InitialMode initialmode)
{
	sendWifiInformation("AndroidAP_3877","sivpt4ezkcuk23z",2,0);
	sendSetup( 3, 0, 0, NULL, 0 );
	return 1;
}

void SdCarplay::stop()
{

}

void SdCarplay::setCarplayAudioMode(bool release)
{

}

SdCarplay::CarplayState SdCarplay::getCarplayState()
{

	return CarplayStateInit;
}
void SdCarplay::sendSingleTouchscreen(unsigned short x, unsigned short y, bool pressed)
{

}
void SdCarplay::sendMulPtrTouchscreen(unsigned char idx0, unsigned short x0, unsigned short y0, bool pressed0, unsigned char idx1, unsigned short x1, unsigned short y1, bool pressed1)
{

}
void SdCarplay::sendTelephoneButton(TelButton button, bool pressed)
{

}
void SdCarplay::sendMediaButton(MediaButton button, bool pressed)
{

}
void SdCarplay::sendSiriButton(bool pressed)
{
    int siri_action;
    if (pressed == 0) {
        siri_action = 2;
    }
    else {
        siri_action = 3;
    }
    sendRequestSiriAction(siri_action);
}
void SdCarplay::sendKnobUpdate(char 	selectButtonPressed,
        char 	homeButtonPressed,
        char 	backButtonPressed,
        double	x,
        double	y,
        char	wheelPositionRelative)
{

}
void SdCarplay::forceKeyFrame(void)
{
	 sendForceKeyFrame();
}
void SdCarplay::requestUI(AppleUIApp app)
{
    char const* strmap="maps:";
    char const* strphone="mobilephone:";
    char const* strnowplaying="nowplaying:";
    char const* strmusice="music:";
    char const* strSend = NULL;

    switch (app) {
        case AppleUIAppMap:
            strSend = strmap;
            break;
        case AppleUIAppPhone:
            strSend = strphone;
            break;
        case AppleUIAppNowPlaying:
            strSend = strnowplaying;
            break;
        case AppleUIAppMusic:
            strSend = strmusice;
            break;
        case AppleUIAppNomal:
            sendRequestUi();
            break;
        default:
            break;
    }

    if (app != AppleUIAppNomal) {
        sendRequestUiWithUrl(strSend);
    }
}
void SdCarplay::setNightMode(bool enter)
{
	sendSetNightMode(enter);
}
void SdCarplay::changeModes(CarplayTransferType 		inScreenType,
        CarplayTransferPriority		inScreenPriority,
        CarplayConstraint			inScreenTake,
        CarplayConstraint			inScreenBorrow,
        CarplayTransferType 		inAudioType,
        CarplayTransferPriority		inAudioPriority,
        CarplayConstraint			inAudioTake,
        CarplayConstraint			inAudioBorrow,
        CarplayTriState				inPhone,
        CarplaySpeechMode			inSpeech,
        CarplayTriState				inTurnByTurn)
{
    sendChangeModes("", inScreenType, inScreenPriority, inScreenTake, inScreenBorrow, "", inAudioType,
                    inAudioPriority, inAudioTake, inAudioBorrow, inPhone, inSpeech, inTurnByTurn);
}
void SdCarplay::playStream(int handle, void *buffer, int len, int frames, unsigned long long timestamp)
{

}
void SdCarplay::recordStream(int handle, void *buffer, int len, int frames, unsigned long long timestamp)
{

}
void SdCarplay::setBtAddr(char mac[6])
{
	setBtMacAddr(mac);
}
int SdCarplay::readIap2DataProc(char *buf, int len)
{
    return sendRfcommData(buf,len);
}
void SdCarplay::setEncryptText(std::string &encryptText)
{

}
std::string SdCarplay::rsaPubEncrypt(const std::string &clearText, const std::string &pubKey)
{
	return "";

}

void SdCarplay::setValue(const char *key, int value, bool save)
{

}
void SdCarplay::setValue(const char *key, const char *value, bool save)
{

}
int SdCarplay::getIntValue(const char *key)
{

	return 0;
}
const char * SdCarplay::getStringValue(const char *key)
{

	return "";
}
